use serialport::{ClearBuffer, DataBits, FlowControl, Parity, SerialPort, StopBits};
use std::sync::{Arc, Mutex};
use std::{ str};
use tauri::{AppHandle, Emitter,  State};
use regex::Regex;
use std::str::FromStr;

// 串口配置
#[derive(serde::Deserialize, serde::Serialize)]
pub struct SerialConfig {
    pub com_port: String,
    pub baud_rate: Option<u32>,
    pub data_bits: Option<u8>,
    pub stop_bits: Option<u8>,
    pub parity: Option<String>,
    pub flow_control: Option<String>,
    pub is_hex: Option<bool>,
    pub msg: Option<String>,
}

// 响应结构体
#[derive(serde::Serialize)]
pub struct Response<T> {
    pub code: u32,
    pub msg: String,
    pub data: Option<T>,
}

// 串口状态管理
pub struct SerialPortState {
    connected_ports: Arc<Mutex<Vec<Box<dyn SerialPort>>>>,
    is_listening: Arc<Mutex<bool>>, 
    is_connected: Arc<Mutex<bool>>,
}

impl SerialPortState {
    pub fn new() -> Self {
        Self {
            connected_ports: Arc::new(Mutex::new(Vec::new())),
            is_listening: Arc::new(Mutex::new(true)),
            is_connected: Arc::new(Mutex::new(false)),
        }
    }

    fn is_connected(&self, com_port: &str) -> bool {
        let ports = self.connected_ports.lock().unwrap();
        ports.iter().any(|entry| entry.name().unwrap() == com_port)
    }

    fn add_port(&self, port: Box<dyn SerialPort>) {
        let mut ports = self.connected_ports.lock().unwrap();
        ports.push(port);
    }

    // 删除端口，需要关闭串口，并关闭循环发送数据
    fn remove_port(&self, com_port: &str) {
        //断开状态
        *self.is_connected.lock().unwrap() = false;
        let mut ports = self.connected_ports.lock().unwrap();
        if let Some(index) = ports
           .iter()
           .position(|entry| entry.name().unwrap() == com_port)
        {
            let mut port = ports.remove(index);
            let _ = port.clear(ClearBuffer::All);
            //关闭
            drop(port);
        }
    }

    fn pause_listening(&self) {
        *self.is_listening.lock().unwrap() = false;
    }

    fn resume_listening(&self) {
        *self.is_listening.lock().unwrap() = true;
    }
}

// 连接串口
#[tauri::command]
pub fn connect_serial_port(
    config: SerialConfig,
    app: AppHandle,
    state: State<SerialPortState>,
) -> serde_json::Value {
  
    if state.is_connected(&config.com_port) {
        return serde_json::to_value(Response {
            code: 1,
            msg: "串口已经链接了".to_string(),
            data: None::<()>,
        }).unwrap();
    }

    // 配置串口参数
    let baud_rate = config.baud_rate.unwrap_or(9600);
    let data_bits = match config.data_bits.unwrap_or(8) {
        5 => DataBits::Five,
        6 => DataBits::Six,
        7 => DataBits::Seven,
        8 => DataBits::Eight,
        _ => DataBits::Eight,
    };
    let stop_bits = match config.stop_bits.unwrap_or(1) {
        2 => StopBits::Two,
        _ => StopBits::One,
    };
    let parity = match config.parity.as_deref().unwrap_or("none") {
        "even" => Parity::Even,
        "odd" => Parity::Odd,
        _ => Parity::None,
    };
    let flow_control = match config.flow_control.as_deref().unwrap_or("none") {
        "software" => FlowControl::Software,
        "hardware" => FlowControl::Hardware,
        _ => FlowControl::None,
    };
    let is_hex = config.is_hex.unwrap_or(false);

    // 创建串口实例
    match serialport::new(&config.com_port, baud_rate)
       .data_bits(data_bits)
       .stop_bits(stop_bits)
       .parity(parity)
       .flow_control(flow_control)
       .open()
    {
        Ok(mut p) => { 
            // 设置连接状态
            *state.is_connected.lock().unwrap() = true;
            // 设置读取超时 
            match p.set_timeout(std::time::Duration::from_millis(100)) {
                Ok(_) => {}
                Err(e) => {
                    return serde_json::to_value(Response {
                        code: 1,
                        msg: format!("Failed to set timeout: {}", e),
                        data: None::<()>,
                    }).unwrap()
                }
            }
         
       

            //state clone
            let state_clone = Arc::clone(&state.connected_ports);
            let is_listening_clone = Arc::clone(&state.is_listening);
            let is_connected_clone = Arc::clone(&state.is_connected);
            // 启动数据读取线程
            std::thread::spawn(move || {
                let mut buffer = vec![0; 1024];
                let mut temp_buffer = Vec::new(); // 用于暂存数据
                loop {
                    // 判断是否连接
                    if !*is_connected_clone.lock().unwrap() {
                        break;
                    }
                    // 判断是否暂停监听
                    if !*is_listening_clone.lock().unwrap() {
                        continue;
                    }
                    // 判断串口是否打开 is_connected
                    
                    let mut ports = match state_clone.lock() {
                        Ok(ports) => ports,
                        Err(_) => {
                            eprintln!("Failed to lock connected_ports");
                            break;
                        },
                    } ;



                    let p_clone = match ports.iter_mut().find(|entry| entry.name().unwrap() == config.com_port){
                        Some(port) => port ,
                        None => {
                            eprintln!("Failed to find port: {}", config.com_port);
                            break;
                        }
                    } ;
                    
                    

                    match p_clone.read(buffer.as_mut_slice()) {
                        Ok(bytes_read) => {
                            if bytes_read > 0 {
                                // 读取到数据
                                let data = &buffer[..bytes_read];
                                temp_buffer.extend_from_slice(data); // 将数据暂存到缓冲区

                                // 查找换行符
                                while let Some(pos) = find_newline(&temp_buffer) {
                                    let line = temp_buffer.drain(..pos + 1).collect::<Vec<u8>>(); // 提取一行数据，包括换行符
                                    let serial_data = if is_hex {
                                        line.iter().map(|b| format!("{:02X}", b)).collect::<Vec<String>>().join(" ")
                                    } else {
                                        match str::from_utf8(&line) {
                                            Ok(valid_str) => valid_str.trim_end_matches(&['\r', '\n'][..]).to_string(),
                                            Err(e) => {
                                                eprintln!("Failed to decode UTF-8: {}", e);
                                                continue;
                                            }
                                        }
                                    };
                                    //判断是否为空
                                    if serial_data.is_empty() {
                                        continue;
                                    }
                                    // 发送数据
                                    app.emit("serial_data", serial_data).unwrap();
                                }
                            }
                        }
                        Err(e) => {
                            // 读取失败
                            if e.kind() != std::io::ErrorKind::TimedOut {
                                eprintln!("Failed to read from port: {}", e);
                                break;
                            }
                        }
                    }
                }
            });

            state.add_port(p);
        }
        Err(e) => {
            return serde_json::to_value(Response {
                    code: 1,
                    msg: format!("端口打开失败: {}", e),
                    data: None::<()>,
                }).unwrap();
        }
    }

    return serde_json::to_value(Response {
        code: 0,
        msg: "串口打开成功！".to_string(),
        data: None::<()>,
    }).unwrap();
}

// 查找 \r\n 的位置
pub fn find_newline(buffer: &[u8]) -> Option<usize> {
    for i in 0..buffer.len() - 1 {
        if buffer[i] == b'\r' || buffer[i] == b'\n' {
            return Some(i);
        }
    }
    None
}

// 断开串口
#[tauri::command]
pub fn disconnect_serial_port(
    config: SerialConfig,
    state: State<SerialPortState>,
) -> serde_json::Value {
    // 暂停监听
    state.pause_listening();
    if !state.is_connected(&config.com_port) {
        return serde_json::to_value(Response {
            code: 1,
            msg: config.com_port + "串口已经断开了！",
            data: None::<()>,
        }).unwrap();
    }

    state.remove_port(&config.com_port);

    return serde_json::to_value(Response {
        code: 0,
        msg: config.com_port + "串口已经断开成功！",
        data: None::<()>,
    }).unwrap();
}

//send_msg,发送数据
#[tauri::command]
pub fn send_msg(
    config: SerialConfig,
    state: State<SerialPortState>,
) -> serde_json::Value {
    // 暂停监听
    state.pause_listening();

    // 获取连接的串口
    let mut ports = state.connected_ports.lock().unwrap();
    let port = ports.iter_mut().find(|entry| entry.name().unwrap() == config.com_port);
    if let Some(port) = port {
        // 发送消息
        if let Some(msg) = &config.msg {
            let mut sendmsg = parse_ascii(msg).as_bytes().to_vec();
            // 发送数据
            match port.write(sendmsg.as_slice()) {
                Ok(_) => {
                    // 恢复监听
                    state.resume_listening();
                    return serde_json::to_value(Response {
                        code: 0,
                        msg: "消息发送成功".to_string(),
                        data: None::<()>,
                    }).unwrap();
                }
                Err(e) => {
                    // 恢复监听
                    state.resume_listening();
                    return serde_json::to_value(Response {
                        code: 1,
                        msg: format!("消息发送失败: {}", e),
                        data: None::<()>,
                    }).unwrap();
                }
            }
        } else {
            // 恢复监听
            state.resume_listening();
            return serde_json::to_value(Response {
                code: 1,
                msg: "消息内容为空".to_string(),
                data: None::<()>,
            }).unwrap();
        }
    } else {
        // 恢复监听
        state.resume_listening();
        return serde_json::to_value(Response {
            code: 1,
            msg: "串口未未连接".to_string(),
            data: None::<()>,
        }).unwrap();
    }
}

// 定义 ParseASCII 函数，用于将字符串中中括号括起来的内容转换为 ASCII 字符
fn parse_ascii(s: &str) -> String {
    // 编译正则表达式，用于匹配中括号内的内容
    let re = Regex::new(r"\[(.*?)\]").expect("Invalid regex");
    let mut result = s.to_string();

    // 遍历所有匹配的内容
    for caps in re.captures_iter(s) {
        // 获取中括号内的内容
        if let Some(m) = caps.get(1) {
            let inner_str = m.as_str();
            // 将字符串转换为 i64 类型的整数
            if let Ok(num) = i64::from_str(inner_str) {
                // 确保整数在有效的 ASCII 范围内
                if num >= 0 && num <= 127 {
                    let ascii_char = char::from(num as u8);
                    // 替换原字符串中的匹配内容为对应的 ASCII 字符
                    result = result.replace(&format!("[{}]", inner_str), &ascii_char.to_string());
                }
            }
        }
    }

    result
}